package l1j.server.server.model.damage;

import static l1j.server.server.model.skill.L1SkillId.COOKING_1_0_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_1_1_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_1_2_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_1_3_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_1_4_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_1_5_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_1_6_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_1_7_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_2_0_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_2_1_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_2_2_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_2_3_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_2_4_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_2_5_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_2_6_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_2_7_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_3_0_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_3_1_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_3_2_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_3_3_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_3_4_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_3_5_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_3_6_S;
import static l1j.server.server.model.skill.L1SkillId.COOKING_3_7_S;
import static l1j.server.server.model.skill.L1SkillId.DRAGON_SKIN;
import static l1j.server.server.model.skill.L1SkillId.EARTH_BIND;
import static l1j.server.server.model.skill.L1SkillId.FREEZING_BLIZZARD;
import static l1j.server.server.model.skill.L1SkillId.FREEZING_BREATH;
import static l1j.server.server.model.skill.L1SkillId.ICE_LANCE;
import static l1j.server.server.model.skill.L1SkillId.ICE_LANCE_BASILISK;
import static l1j.server.server.model.skill.L1SkillId.ICE_LANCE_COCKATRICE;
import static l1j.server.server.model.skill.L1SkillId.PATIENCE;
import static l1j.server.server.model.skill.L1SkillId.REDUCTION_ARMOR;
import static l1j.server.server.model.skill.L1SkillId.IMMUNE_TO_HARM;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import l1j.server.L1DatabaseFactory;
import l1j.server.server.model.L1Character;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.damage.magic.L1MagicDamage_Npc_Npc;
import l1j.server.server.model.damage.magic.L1MagicDamage_Npc_Pc;
import l1j.server.server.model.damage.magic.L1MagicDamage_Pc_Npc;
import l1j.server.server.model.damage.magic.L1MagicDamage_Pc_Pc;
import l1j.server.server.model.damage.physical.L1PhysicalDamage_Npc_Npc;
import l1j.server.server.model.damage.physical.L1PhysicalDamage_Npc_Pc;
import l1j.server.server.model.damage.physical.L1PhysicalDamage_Pc_Npc;
import l1j.server.server.model.damage.physical.L1PhysicalDamage_Pc_Pc;
import l1j.server.server.utils.SQLUtil;

public abstract class L1Dmg {
	protected static final int[] mr_reduction_chance = new int[601];// -100~+500

	protected static final int[] mr_reduction_percent = new int[601];// -100~+500

	protected static final int[] attr_reduction_percent = new int[601];// -300~+300

	static {
		Connection con = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			con = L1DatabaseFactory.getInstance().getConnection();
			pstm = con.prepareStatement("select * from x_mr_attr");
			rs = pstm.executeQuery();
			while (rs.next()) {
				int mr = rs.getInt("mr");
				mr_reduction_chance[mr + 100] = rs
						.getInt("mr_reduction_chance");
				mr_reduction_percent[mr + 100] = rs
						.getInt("mr_reduction_percent");
				attr_reduction_percent[rs.getInt("attr") + 300] = rs
						.getInt("attr_reduction_percent");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			SQLUtil.close(pstm);
			SQLUtil.close(con);
			SQLUtil.close(rs);
		}
	}

	public static L1Dmg get(boolean isMagic, int attr, L1Character attacker,
			L1Character target) {
		// 魔法
		if (isMagic) {
			if (attacker instanceof L1PcInstance) {
				if (target instanceof L1PcInstance) {
					return new L1MagicDamage_Pc_Pc((L1PcInstance) attacker,
							(L1PcInstance) target, attr);
				}
				return new L1MagicDamage_Pc_Npc((L1PcInstance) attacker,
						(L1NpcInstance) target, attr);
			} else {
				if (target instanceof L1PcInstance) {
					return new L1MagicDamage_Npc_Pc((L1NpcInstance) attacker,
							(L1PcInstance) target, attr);
				}
				return new L1MagicDamage_Npc_Npc((L1NpcInstance) attacker,
						(L1NpcInstance) target, attr);
			}
		}

		// 物理
		if (attacker instanceof L1PcInstance) {
			if (target instanceof L1PcInstance) {
				return new L1PhysicalDamage_Pc_Pc((L1PcInstance) attacker,
						(L1PcInstance) target);
			}
			return new L1PhysicalDamage_Pc_Npc((L1PcInstance) attacker,
					(L1NpcInstance) target);
		} else {
			if (target instanceof L1PcInstance) {
				return new L1PhysicalDamage_Npc_Pc((L1NpcInstance) attacker,
						(L1PcInstance) target);
			}
			return new L1PhysicalDamage_Npc_Npc((L1NpcInstance) attacker,
					(L1NpcInstance) target);
		}

	}

	public L1Dmg add(double v) {
		dmg += v;
		return this;
	}

	public L1Dmg sub(double v) {
		dmg -= v;
		return this;
	}

	public L1Dmg mul(double v) {
		dmg *= v;
		return this;
	}

	public L1Dmg div(double v) {
		dmg /= v;
		return this;
	}

	public abstract void hurtTarget(boolean actionHurt);

	private int dmg = 0;

	public void zero() {
		dmg = 0;
	}

	public double getValue() {
		return dmg;
	}

	public abstract void calcDmg();

	protected void commitAttacker(L1Character attacker) {

	}

	public void commitMagic(L1Character target) {

	}
	
	public void commitAttrByWp(double dmg) {
		
	}

	protected void commitTarget(L1Character target) {
		if (target.hasSkillEffect(COOKING_1_0_S) // 料理によるダメージ軽減
				|| target.hasSkillEffect(COOKING_1_1_S)
				|| target.hasSkillEffect(COOKING_1_2_S)
				|| target.hasSkillEffect(COOKING_1_3_S)
				|| target.hasSkillEffect(COOKING_1_4_S)
				|| target.hasSkillEffect(COOKING_1_5_S)
				|| target.hasSkillEffect(COOKING_1_6_S)
				|| target.hasSkillEffect(COOKING_2_0_S)
				|| target.hasSkillEffect(COOKING_2_1_S)
				|| target.hasSkillEffect(COOKING_2_2_S)
				|| target.hasSkillEffect(COOKING_2_3_S)
				|| target.hasSkillEffect(COOKING_2_4_S)
				|| target.hasSkillEffect(COOKING_2_5_S)
				|| target.hasSkillEffect(COOKING_2_6_S)
				|| target.hasSkillEffect(COOKING_3_0_S)
				|| target.hasSkillEffect(COOKING_3_1_S)
				|| target.hasSkillEffect(COOKING_3_2_S)
				|| target.hasSkillEffect(COOKING_3_3_S)
				|| target.hasSkillEffect(COOKING_3_4_S)
				|| target.hasSkillEffect(COOKING_3_5_S)
				|| target.hasSkillEffect(COOKING_3_6_S)) {
			dmg -= 5;
		}
		if (target.hasSkillEffect(COOKING_1_7_S) // デザートによるダメージ軽減
				|| target.hasSkillEffect(COOKING_2_7_S)
				|| target.hasSkillEffect(COOKING_3_7_S)) {
			dmg -= 5;
		}
		if (target.hasSkillEffect(REDUCTION_ARMOR)) {
			int targetPcLvl = target.getLevel();
			if (targetPcLvl < 50) {
				targetPcLvl = 50;
			}
			dmg -= (targetPcLvl - 50) / 5 + 1;
		}

		if (target.hasSkillEffect(DRAGON_SKIN)) {
			dmg -= 2;
		}
		if (target.hasSkillEffect(PATIENCE)) {
			dmg -= 2;
		}
		if (target.hasSkillEffect(IMMUNE_TO_HARM)) {
			dmg /= 2;
		}

		if (target.hasSkillEffect(ICE_LANCE)) {
			dmg = 0;
		}
		if (target.hasSkillEffect(FREEZING_BLIZZARD)) {
			dmg = 0;
		}
		if (target.hasSkillEffect(FREEZING_BREATH)) {
			dmg = 0;
		}
		if (target.hasSkillEffect(EARTH_BIND)) {
			dmg = 0;
		}
		if (target.hasSkillEffect(ICE_LANCE_COCKATRICE)) {
			dmg = 0;
		}
		if (target.hasSkillEffect(ICE_LANCE_BASILISK)) {
			dmg = 0;
		}

	}
}
